home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / pbmtopk / pbmtopk / pbmtopk.c < prev    next >
C/C++ Source or Header  |  1991-10-29  |  25KB  |  1,051 lines

  1. /*
  2.   pbmtopk, adapted from "pxtopk.c by tomas rokicki" by AJCD 1/8/90
  3.   
  4.   compile with: cc -o pbmtopk pbmtopk.c -lm -lpbm
  5.   */
  6.  
  7. #include <stdio.h>
  8. #include <pbm.h>
  9. #include <ctype.h>
  10.  
  11. extern double atof();
  12.  
  13. #define MAXPKCHAR 256
  14. #define MAXOPTLINE 200
  15. #define MAXWIDTHTAB 256
  16. #define MAXHEIGHTTAB 16
  17. #define MAXDEPTHTAB 16
  18. #define MAXITALICTAB 64
  19. #define MAXPARAMS 30
  20. #define NAMELENGTH 80
  21.  
  22. #define true (1)
  23. #define false (0)
  24. #define chr(a) a
  25.   
  26. #define round(a) ((int)(a+.5))
  27. #define fixword(d) ((int)((double)(d)*1048576))
  28. #define unfixword(f) ((double)(f) / 1048576)
  29. #define fixrange(f) ((f) < 16777216 && (f) > -16777216)
  30. #define designunits(p) ((p)*72.27/(double)resolution/unfixword(designsize))
  31.  
  32. /* character flags: in order of appearance in option files. */
  33. #define XOFFSET     1
  34. #define YOFFSET     2
  35. #define HORZESC     4
  36. #define VERTESC     8
  37. #define TFMWIDTH   16
  38. #define TFMHEIGHT  32
  39. #define TFMDEPTH   64
  40. #define TFMITALIC 128
  41.  
  42. typedef int integer ;
  43. typedef char quarterword ;
  44. typedef char boolean ;
  45. typedef quarterword ASCIIcode ;
  46. typedef quarterword eightbits ;
  47. typedef FILE *bytefile ;
  48. typedef unsigned char byte ;
  49.  
  50. integer resolution, designsize ;
  51. char *filename[MAXPKCHAR] ;
  52.  
  53. integer xoffset[MAXPKCHAR] ;
  54. integer yoffset[MAXPKCHAR] ;
  55. integer horzesc[MAXPKCHAR] ;
  56. integer vertesc[MAXPKCHAR] ;
  57.  
  58. byte tfmindex[MAXPKCHAR] ;
  59. byte hgtindex[MAXPKCHAR] ;
  60. byte depindex[MAXPKCHAR] ;
  61. byte italindex[MAXPKCHAR] ;
  62. byte charflags[MAXPKCHAR] ;
  63.  
  64. bit **bitmap ;
  65. integer smallestch, largestch ;
  66. integer emwidth ;
  67. integer checksum ;
  68. char *codingscheme = "GRAPHIC" ;
  69. char *familyname = "PBM" ;
  70.  
  71. integer widthtab[MAXWIDTHTAB] ; /* TFM widths */
  72. integer numwidth ;      /* number of entries in width table */
  73. integer heighttab[MAXHEIGHTTAB] ;
  74. integer numheight ;
  75. integer depthtab[MAXDEPTHTAB] ;
  76. integer numdepth ;
  77. integer italictab[MAXITALICTAB] ;
  78. integer numitalic ;
  79. integer parameters[MAXPARAMS] ;
  80. integer numparam ;
  81.  
  82. ASCIIcode xord[128] ;
  83. char xchr[256] ;
  84. bytefile tfmfile, pkfile ;
  85. char tfmname[NAMELENGTH+1], pkname[NAMELENGTH+1] ;
  86. integer pkloc ;
  87. integer bitweight ;
  88. integer outputbyte ;
  89. integer car ;
  90. integer hppp ;
  91. integer width ;
  92. integer height ;
  93. integer power[32] ;
  94.  
  95. integer
  96. compute_checksum()
  97. {
  98.   /*
  99.     begin
  100.       c0:=bc; c1:=ec; c2:=bc; c3:=ec;
  101.       for c:=bc to ec do if char_wd[c]>0 then
  102.     begin
  103.       temp_width:=memory[char_wd[c]];
  104.       if design_units<>unity then
  105.         temp_width:=round((temp_width/design_units)*1048576.0);
  106.       temp_width:=temp_width + (c+4)*@'20000000; {this should be positive}
  107.       c0:=(c0+c0+temp_width) mod 255;
  108.       c1:=(c1+c1+temp_width) mod 253;
  109.       c2:=(c2+c2+temp_width) mod 251;
  110.       c3:=(c3+c3+temp_width) mod 247;
  111.     end;
  112.       header_bytes[check_sum_loc]:=c0;
  113.       header_bytes[check_sum_loc+1]:=c1;
  114.       header_bytes[check_sum_loc+2]:=c2;
  115.       header_bytes[check_sum_loc+3]:=c3;
  116.     end
  117.     */
  118. }
  119.  
  120. #define add_tfmwidth(v) (add_tfmtable(widthtab, &numwidth, v, MAXWIDTHTAB,\
  121.                       "TFM width"))
  122. #define add_tfmheight(v) (add_tfmtable(heighttab, &numheight, v, MAXHEIGHTTAB,\
  123.                        "TFM height"))
  124. #define add_tfmdepth(v) (add_tfmtable(depthtab, &numdepth, v, MAXDEPTHTAB,\
  125.                       "TFM depth"))
  126. #define add_tfmitalic(v) (add_tfmtable(italictab, &numitalic, v, MAXITALICTAB,\
  127.                        "Italic correction"))
  128. byte
  129. add_tfmtable(table, count, value, maxv, name)
  130.      integer *table, *count, value, maxv;
  131.      char *name;
  132. {
  133.   integer i;
  134.   for (i = 0; i < *count; i++) /* search for value in tfm table */
  135.     if (table[i] == value) return (byte)i;
  136.   if (*count >= maxv) {
  137.     fprintf(stderr, "Too many values in %s table!\n", name) ;
  138.     jumpout();
  139.   }
  140.   if (!fixrange(value)) {
  141.     fprintf(stderr, " %s %f for char %d out of range!\n",
  142.         name, unfixword(value), car);
  143.     jumpout();
  144.   }
  145.   table[*count] = value ;
  146.   return (*count)++ ;
  147. }
  148.  
  149. add_suffix(name, suffix)
  150.      char *name, *suffix ;
  151. {
  152.   int haveext = 0;
  153.   if (name && strcmp(name, "-")) {
  154.     while (*name) {
  155.       if (*name == '/') haveext = 0 ;
  156.       else if (*name == '.') haveext = 1 ;
  157.       name++ ;
  158.     }
  159.     if (!haveext) {
  160.       *name++ = '.';
  161.       strcpy(name,suffix) ;
  162.     }
  163.   }
  164. }
  165.  
  166. initialize()
  167. {
  168.   integer i ;
  169.   fprintf(stderr, "This is PBMtoPK, C Version 2.3\n") ;
  170.   for (i = 0 ; i <= 31 ; i ++) xchr[i] = '?' ;
  171.   xchr[32] = ' ' ;
  172.   xchr[33] = '!' ;
  173.   xchr[34] = '"' ;
  174.   xchr[35] = '#' ;
  175.   xchr[36] = '$' ;
  176.   xchr[37] = '%' ;
  177.   xchr[38] = '&' ;
  178.   xchr[39] = '\'' ;
  179.   xchr[40] = '(' ;
  180.   xchr[41] = ')' ;
  181.   xchr[42] = '*' ;
  182.   xchr[43] = '+' ;
  183.   xchr[44] = ',' ;
  184.   xchr[45] = '-' ;
  185.   xchr[46] = '.' ;
  186.   xchr[47] = '/' ;
  187.   xchr[48] = '0' ;
  188.   xchr[49] = '1' ;
  189.   xchr[50] = '2' ;
  190.   xchr[51] = '3' ;
  191.   xchr[52] = '4' ;
  192.   xchr[53] = '5' ;
  193.   xchr[54] = '6' ;
  194.   xchr[55] = '7' ;
  195.   xchr[56] = '8' ;
  196.   xchr[57] = '9' ;
  197.   xchr[58] = ':' ;
  198.   xchr[59] = ';' ;
  199.   xchr[60] = '<' ;
  200.   xchr[61] = '=' ;
  201.   xchr[62] = '>' ;
  202.   xchr[63] = '?' ;
  203.   xchr[64] = '@' ;
  204.   xchr[65] = 'A' ;
  205.   xchr[66] = 'B' ;
  206.   xchr[67] = 'C' ;
  207.   xchr[68] = 'D' ;
  208.   xchr[69] = 'E' ;
  209.   xchr[70] = 'F' ;
  210.   xchr[71] = 'G' ;
  211.   xchr[72] = 'H' ;
  212.   xchr[73] = 'I' ;
  213.   xchr[74] = 'J' ;
  214.   xchr[75] = 'K' ;
  215.   xchr[76] = 'L' ;
  216.   xchr[77] = 'M' ;
  217.   xchr[78] = 'N' ;
  218.   xchr[79] = 'O' ;
  219.   xchr[80] = 'P' ;
  220.   xchr[81] = 'Q' ;
  221.   xchr[82] = 'R' ;
  222.   xchr[83] = 'S' ;
  223.   xchr[84] = 'T' ;
  224.   xchr[85] = 'U' ;
  225.   xchr[86] = 'V' ;
  226.   xchr[87] = 'W' ;
  227.   xchr[88] = 'X' ;
  228.   xchr[89] = 'Y' ;
  229.   xchr[90] = 'Z' ;
  230.   xchr[91] = '[' ;
  231.   xchr[92] = '\\' ;
  232.   xchr[93] = ']' ;
  233.   xchr[94] = '^' ;
  234.   xchr[95] = '_' ;
  235.   xchr[96] = '`' ;
  236.   xchr[97] = 'a' ;
  237.   xchr[98] = 'b' ;
  238.   xchr[99] = 'c' ;
  239.   xchr[100] = 'd' ;
  240.   xchr[101] = 'e' ;
  241.   xchr[102] = 'f' ;
  242.   xchr[103] = 'g' ;
  243.   xchr[104] = 'h' ;
  244.   xchr[105] = 'i' ;
  245.   xchr[106] = 'j' ;
  246.   xchr[107] = 'k' ;
  247.   xchr[108] = 'l' ;
  248.   xchr[109] = 'm' ;
  249.   xchr[110] = 'n' ;
  250.   xchr[111] = 'o' ;
  251.   xchr[112] = 'p' ;
  252.   xchr[113] = 'q' ;
  253.   xchr[114] = 'r' ;
  254.   xchr[115] = 's' ;
  255.   xchr[116] = 't' ;
  256.   xchr[117] = 'u' ;
  257.   xchr[118] = 'v' ;
  258.   xchr[119] = 'w' ;
  259.   xchr[120] = 'x' ;
  260.   xchr[121] = 'y' ;
  261.   xchr[122] = 'z' ;
  262.   xchr[123] = '{' ;
  263.   xchr[124] = '|' ;
  264.   xchr[125] = '}' ;
  265.   xchr[126] = '~' ;
  266.   for (i = 127 ; i <= 255 ; i ++) xchr[i] = '?' ;
  267.   for (i = 0 ; i <= 127 ; i ++) xord[chr(i)] = 32 ;
  268.   for (i = 32 ; i <= 126 ; i ++) xord[xchr[i]] = i ;
  269.   for (i = 0 ; i < 32 ; i++) power[i] = 1 << i ;
  270.   for (i = 0; i < MAXPKCHAR; i++) {
  271.     filename[i] = NULL;
  272.     charflags[i] = 0;
  273.   }
  274.   pkloc = 0 ;
  275.   designsize = fixword(1.0) ;
  276.   numparam = 0;
  277.   widthtab[0] = heighttab[0] = depthtab[0] = italictab[0] = 0 ;
  278.   numwidth = numheight = numdepth = numitalic = 1;
  279.   smallestch = MAXPKCHAR ;
  280.   largestch = -1 ;
  281.   emwidth = 0 ;
  282. }
  283.  
  284. jumpout()
  285. {
  286.   exit(1) ;
  287. }
  288.  
  289. pkbyte(b)
  290.      integer b ;
  291. {
  292.   if (b < 0) b = b + 256 ;
  293.   putc(b, pkfile) ;
  294.   pkloc++ ;
  295. }
  296.  
  297. pkhalfword(a)
  298.      integer a ;
  299. {
  300.   if (a < 0) a = a + 65536 ;
  301.   pkbyte(a >> 8) ;
  302.   pkbyte(a & 255) ;
  303. }
  304.  
  305. pkthreebytes(a)
  306.      integer a ;
  307. {
  308.   pkbyte((a>>16) & 255) ;
  309.   pkbyte((a>>8) & 255) ;
  310.   pkbyte(a & 255) ;
  311. }
  312.  
  313. pkword(a)
  314.      integer a ;
  315. {
  316.   pkbyte((a>>24) & 255) ;
  317.   pkbyte((a>>16) & 255) ;
  318.   pkbyte((a>>8) & 255) ;
  319.   pkbyte(a & 255) ;
  320. }
  321.  
  322. pknyb(a)
  323.      integer a ;
  324. {
  325.   if (bitweight == 16) {
  326.     outputbyte = (a<<4) ;
  327.     bitweight = 1 ;
  328.   } else {
  329.     pkbyte(outputbyte + a) ;
  330.     bitweight = 16 ;
  331.   }
  332. }
  333.  
  334. writepreamble()
  335. {
  336.   integer i ;
  337.   char *comment = "PBMtoPK 2.3 output" ;
  338.   
  339.   pkbyte(247) ;
  340.   pkbyte(89) ;
  341.   pkbyte(strlen(comment)) ;
  342.   for (i = 0 ; i < strlen(comment); i++) pkbyte(xord[comment[i]]) ;
  343.   pkword(designsize) ;
  344.   pkword(checksum) ; /* checksum; calculate if possible */
  345.   pkword(hppp) ;
  346.   pkword(hppp) ;
  347. }
  348.  
  349. writepostamble()
  350. {
  351.   pkbyte(245) ;
  352.   while ((pkloc % 4 != 0)) pkbyte(246) ;
  353.   fprintf(stderr, "%d bytes written to packed file.\n", pkloc) ;
  354. }
  355.  
  356. tfmbyte(b)
  357.      integer b ;
  358. {
  359.   if (b < 0) b = b + 256 ;
  360.   putc(b, tfmfile) ;
  361. }
  362.  
  363. tfmhalfword(a)
  364.      integer a ;
  365. {
  366.   if (a < 0) a = a + 65536 ;
  367.   tfmbyte(a >> 8) ;
  368.   tfmbyte(a & 255) ;
  369. }
  370.  
  371. tfmword(a)
  372.      integer a ;
  373. {
  374.   tfmbyte((a>>24) & 255) ;
  375.   tfmbyte((a>>16) & 255) ;
  376.   tfmbyte((a>>8) & 255) ;
  377.   tfmbyte(a & 255) ;
  378. }
  379.  
  380. writetfmfile()
  381. {
  382.   integer totallength ;
  383.   integer headersize = 17;
  384.   integer i ;
  385.  
  386.   if (largestch - smallestch < 0) {
  387.      largestch = 0;
  388.      smallestch = 1;
  389.   }
  390.   if (numparam < 7) /* set default parameters */
  391.     switch (numparam) {
  392.     case 0: /* slant */
  393.       parameters[numparam++] = 0 ;
  394.     case 1: /* space */
  395.       parameters[numparam++] = fixword(designunits(emwidth/3.0));
  396.     case 2: /* space_stretch */
  397.       parameters[numparam++] = fixword(unfixword(parameters[1])/2.0) ;
  398.     case 3: /* space_shrink */
  399.       parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ;
  400.     case 4: /* x_height */
  401.       parameters[numparam++] = fixword(0.45);
  402.     case 5: /* quad */
  403.       parameters[numparam++] = fixword(designunits(emwidth)) ;
  404.     case 6: /* extra_space */
  405.       parameters[numparam++] = fixword(unfixword(parameters[1])/3.0) ;
  406.     }
  407.   totallength = 6 + headersize + (largestch+1-smallestch) +
  408.     numwidth + numheight + numdepth + numitalic + numparam ;
  409.   /* lengths */
  410.   tfmhalfword(totallength) ;
  411.   tfmhalfword(headersize) ;
  412.   tfmhalfword(smallestch) ;
  413.   tfmhalfword(largestch) ;
  414.   tfmhalfword(numwidth) ;
  415.   tfmhalfword(numheight) ;
  416.   tfmhalfword(numdepth) ;
  417.   tfmhalfword(numitalic) ;
  418.   tfmhalfword(0) ; /* lig/kern table */
  419.   tfmhalfword(0) ; /* kern table */
  420.   tfmhalfword(0) ; /* extensible char table */
  421.   tfmhalfword(numparam) ;
  422.   /* header */
  423.   tfmword(checksum) ;
  424.   tfmword(designsize) ;
  425.   if (strlen(codingscheme) > 39) tfmbyte(39) ;
  426.   else tfmbyte(strlen(codingscheme)) ;
  427.   for (i = 0; i < 39; i++)
  428.     if (*codingscheme) tfmbyte(xord[*codingscheme++]) ;
  429.     else tfmbyte(0) ;
  430.   if (strlen(familyname) > 19) tfmbyte(19) ;
  431.   else tfmbyte(strlen(familyname)) ;
  432.   for (i = 0; i < 19; i++)
  433.     if (*familyname) tfmbyte(xord[*familyname++]) ;
  434.     else tfmbyte(0) ;
  435.   /* char_info */
  436.   for (car = smallestch; car <= largestch; car++)
  437.     if (filename[car]) {
  438.       tfmbyte(tfmindex[car]) ;
  439.       tfmbyte((hgtindex[car]<<4) + depindex[car]) ;
  440.       tfmbyte(italindex[car]<<2) ;
  441.       tfmbyte(0) ;
  442.     } else tfmword(0) ;
  443.   /* width */
  444.   for (i = 0; i < numwidth; i++) tfmword(widthtab[i]) ;
  445.   /* height */
  446.   for (i = 0; i < numheight; i++) tfmword(heighttab[i]) ;
  447.   /* depth */
  448.   for (i = 0; i < numdepth; i++) tfmword(depthtab[i]) ;
  449.   /* italic */
  450.   for (i = 0; i < numitalic; i++) tfmword(italictab[i]) ;
  451.   /* no lig_kern, kern, or exten */
  452.   /* param */
  453.   for (i = 0; i < numparam; i++)
  454.     if (i && (!fixrange(parameters[i]))) {
  455.       fprintf(stderr, " Parameter %d out of range (-p)!\n", i);
  456.       jumpout();
  457.     }
  458.     else tfmword(parameters[i]) ;
  459.   fprintf(stderr, "%d bytes written to tfm file.\n", totallength*4) ;
  460. }
  461.  
  462. readcharacter()
  463. {
  464.   FILE *fp;
  465.  
  466.   if (!strcmp(filename[car], "-")) fp = stdin;
  467.   else if ((fp = fopen(filename[car], "r")) == NULL) {
  468.     fprintf(stderr, " Can't open pbm file %s!\n", filename[car]);
  469.     jumpout();
  470.   }
  471.   bitmap = pbm_readpbm(fp, &width, &height) ;
  472.   if (fp != stdin) fclose(fp) ;
  473.   
  474.   if ((charflags[car] & HORZESC) == 0) horzesc[car] = width ;
  475.   if ((charflags[car] & VERTESC) == 0) vertesc[car] = 0;
  476.   if ((charflags[car] & XOFFSET) == 0) xoffset[car] = 0;
  477.   if ((charflags[car] & YOFFSET) == 0) yoffset[car] = height-1;
  478.   if ((charflags[car] & TFMWIDTH) == 0)
  479.     tfmindex[car] = add_tfmwidth(fixword(designunits(width)));
  480.   if ((charflags[car] & TFMHEIGHT) == 0)
  481.     hgtindex[car] = add_tfmheight(fixword(designunits(yoffset[car]+1)));
  482.   if ((charflags[car] & TFMDEPTH) == 0)
  483.     depindex[car] = add_tfmdepth(fixword(designunits(height-1-yoffset[car])));
  484.   if ((charflags[car] & TFMITALIC) == 0) italindex[car] = 0;
  485.  
  486.   if (car < smallestch) smallestch = car;
  487.   if (car > largestch) largestch = car;
  488.   if (width > emwidth) emwidth = width ;
  489. }
  490.  
  491. int
  492. equal(row1, row2)
  493.      bit *row1, *row2 ;
  494. {
  495.   integer i ;
  496.   
  497.   for (i = 0; i < width; i++)
  498.     if (row1[i] != row2[i]) return (0) ;
  499.   return(1) ;
  500. }
  501.  
  502. shipcharacter()
  503. {
  504.   integer compsize ;
  505.   integer i, j, k ;
  506.   bit *zerorow, *onesrow ;
  507.   integer *repeatptr, *bitcounts ;
  508.   integer count ;
  509.   integer test ;
  510.   integer curptr, rowptr ;
  511.   integer bitval ;
  512.   integer repeatflag ;
  513.   integer colptr ;
  514.   integer currepeat ;
  515.   integer dynf ;
  516.   integer deriv[14] ;
  517.   integer bcompsize ;
  518.   boolean firston ;
  519.   integer flagbyte ;
  520.   boolean state ;
  521.   boolean on ;
  522.   integer hbit ;
  523.   integer pbit ;
  524.   boolean ron, son ;
  525.   integer rcount, scount ;
  526.   integer ri, si ;
  527.   integer max2 ;
  528.   integer predpkloc ;
  529.   integer buff ;
  530.  
  531.   integer tfwid = widthtab[tfmindex[car]] ;
  532.   integer hesc = horzesc[car] ;
  533.   integer vesc = vertesc[car] ;
  534.   integer xoff = xoffset[car] ;
  535.   integer yoff = yoffset[car] ;
  536.  
  537.   zerorow = pbm_allocrow(width) ;
  538.   onesrow = pbm_allocrow(width) ;
  539.   repeatptr =
  540.     (integer *)malloc((unsigned int)((height+1)*sizeof(integer))) ;
  541.   bitcounts =
  542.     (integer *)malloc((unsigned int)((height*width)*sizeof(integer))) ;
  543.   if (repeatptr == NULL || bitcounts == NULL) {
  544.      fprintf(stderr, " Out of memory while allocating bit counts!\n");
  545.      jumpout() ;
  546.   }
  547.   for (i = 0 ; i < width ; i++) {
  548.     zerorow[i] = PBM_WHITE ;
  549.     onesrow[i] = PBM_BLACK ;
  550.   }
  551.   for (i=0; i < height; i++) {
  552.     if (equal(bitmap[i], zerorow))
  553.       repeatptr[i] = 0 ;
  554.     else if (equal(bitmap[i], onesrow)) 
  555.       repeatptr[i] = 0 ;
  556.     else if (i + 1 < height && equal(bitmap[i],bitmap[i+1]))
  557.       repeatptr[i] = 1 ;
  558.     else
  559.       repeatptr[i] = 0 ;
  560.   }
  561.   i = 0 ;
  562.   while (i < height) {
  563.     k = i ;
  564.     while (repeatptr[k] == 1) k++ ;
  565.     repeatptr[i] = k - i ;
  566.     i = k + 1 ;
  567.   }
  568.   repeatptr[i] = 0 ;
  569.   colptr = width - 1 ;
  570.   repeatflag = currepeat = curptr = count = rowptr = 0 ;
  571.   test = PBM_WHITE ;
  572.   do {
  573.     colptr++ ;
  574.     if (colptr == width) {
  575.       colptr = 0 ;
  576.       rowptr = currepeat ;
  577.       if (repeatptr[currepeat] > 0) {
  578.     repeatflag = repeatptr[currepeat] ;
  579.     currepeat += repeatflag ;
  580.     rowptr += repeatflag ;
  581.       }
  582.       currepeat++ ;
  583.     }
  584.     if (rowptr >= height) bitval = -1 ;
  585.     else bitval = bitmap[rowptr][colptr] ;
  586.     if (bitval == test) count++ ;
  587.     else {
  588.       bitcounts[curptr++] = count ;
  589.       if (curptr+3 >= height*width) {
  590.     fprintf(stderr, " Out of memory while saving character counts!\n");
  591.     jumpout() ;
  592.       }
  593.       count = 1 ;
  594.       test = bitval ;
  595.       if (repeatflag > 0) {
  596.     bitcounts[curptr++] = -repeatflag ;
  597.     repeatflag = 0 ;
  598.       }
  599.     }
  600.   } while (test != -1) ;
  601.   bitcounts[curptr] = 0 ;
  602.   bitcounts[curptr + 1] = 0 ;
  603.   for (i = 1 ; i <= 13 ; i ++) deriv[i] = 0 ;
  604.   i = firston = (bitcounts[0] == 0) ;
  605.   compsize = 0 ;
  606.   while (bitcounts[i] != 0) {
  607.     j = bitcounts[i] ;
  608.     if (j == -1) compsize++ ;
  609.     else {
  610.       if (j < 0) {
  611.     compsize++ ;
  612.     j = -j ;
  613.       }
  614.       if (j < 209) compsize += 2 ;
  615.       else {
  616.     k = j - 193 ;
  617.     while (k >= 16) {
  618.       k >>= 4 ;
  619.       compsize += 2 ;
  620.     }
  621.     compsize++ ;
  622.       }
  623.       if (j < 14) (deriv[j])-- ;
  624.       else if (j < 209) (deriv[(223 - j) / 15])++ ;
  625.       else {
  626.     k = 16 ;
  627.     while (((k<<4) < j + 3)) k <<= 4 ;
  628.     if (j - k <= 192)
  629.       deriv[(207 - j + k) / 15] += 2 ;
  630.       }
  631.     }
  632.     i++ ;
  633.   }
  634.   bcompsize = compsize ;
  635.   dynf = 0 ;
  636.   for (i = 1 ; i <= 13 ; i ++) {
  637.     compsize += deriv[i] ;
  638.     if (compsize <= bcompsize) {
  639.       bcompsize = compsize ;
  640.       dynf = i ;
  641.     }
  642.   }
  643.   compsize = ((bcompsize + 1)>>1) ;
  644.   if ((compsize > ((height*width+7)>>3)) || (height*width == 0)) {
  645.     compsize = ((height*width+7)>>3) ;
  646.     dynf = 14 ;
  647.   }
  648.   flagbyte = (dynf<<4) ;
  649.   if (firston) flagbyte |= 8 ;
  650.   if ((tfwid > 16777215) || (tfwid < 0) || (hesc < 0) || (vesc != 0) ||
  651.       (compsize > 196579) || (width > 65535) || (height > 65535) ||
  652.       (xoff > 32767) || (yoff > 32767) || (xoff < -32768) || (yoff < -32768)) {
  653.     flagbyte |= 7 ;
  654.     pkbyte(flagbyte) ;
  655.     compsize += 28 ;
  656.     pkword(compsize) ;
  657.     pkword(car) ;
  658.     predpkloc = pkloc + compsize ;
  659.     pkword(tfwid) ;
  660.     pkword(hesc<<16) ;
  661.     pkword(vesc<<16) ;
  662.     pkword(width) ;
  663.     pkword(height) ;
  664.     pkword(xoff) ;
  665.     pkword(yoff) ;
  666.   } else if ((hesc > 255) || (width > 255) || (height > 255) ||
  667.        (xoff > 127) || (yoff > 127) || (xoff < -128) ||
  668.        (yoff < -128) || (compsize > 1016)) {
  669.     compsize += 13 ;
  670.     flagbyte += (compsize>>16) + 4 ;
  671.     pkbyte(flagbyte) ;
  672.     pkhalfword(compsize & 65535) ;
  673.     pkbyte(car) ;
  674.     predpkloc = pkloc + compsize ;
  675.     pkthreebytes(tfwid) ;
  676.     pkhalfword(hesc) ;
  677.     pkhalfword(width) ;
  678.     pkhalfword(height) ;
  679.     pkhalfword(xoff) ;
  680.     pkhalfword(yoff) ;
  681.   } else {
  682.     compsize += 8 ;
  683.     flagbyte = flagbyte + (compsize>>8) ;
  684.     pkbyte(flagbyte) ;
  685.     pkbyte(compsize & 255) ;
  686.     pkbyte(car) ;
  687.     predpkloc = pkloc + compsize ;
  688.     pkthreebytes(tfwid) ;
  689.     pkbyte(hesc) ;
  690.     pkbyte(width) ;
  691.     pkbyte(height) ;
  692.     pkbyte(xoff) ;
  693.     pkbyte(yoff) ;
  694.   }
  695.   if (dynf != 14) {
  696.     bitweight = 16 ;
  697.     max2 = 208 - 15 * dynf ;
  698.     i = firston ;
  699.     while (bitcounts[i] != 0) {
  700.       j = bitcounts[i] ;
  701.       if (j == - 1) pknyb(15) ;
  702.       else {
  703.     if (j < 0) {
  704.       pknyb(14) ;
  705.       j = -j ;
  706.     }
  707.     if (j <= dynf) pknyb(j) ;
  708.     else if (j <= max2) {
  709.       j -= dynf + 1 ;
  710.       pknyb((j >> 4) + dynf + 1) ;
  711.       pknyb((j & 15)) ;
  712.     } else {
  713.       j -= max2 - 15 ;
  714.       k = 16 ;
  715.       while (k <= j) {
  716.         k <<= 4 ;
  717.         pknyb(0) ;
  718.       }
  719.       while (k > 1) {
  720.         k >>= 4 ;
  721.         pknyb(j / k) ;
  722.         j = j % k ;
  723.       }
  724.     }
  725.       }
  726.       i++ ;
  727.     }
  728.     if (bitweight != 16) pkbyte(outputbyte) ;
  729.   } else {
  730.     buff = 0 ;
  731.     pbit = 8 ;
  732.     i = firston ;
  733.     hbit = width ;
  734.     on = ! firston ;
  735.     state = false ;
  736.     count = repeatflag = 0 ;
  737.     while ((bitcounts[i] != 0) || state || (count > 0)) {
  738.       if (state) {
  739.     count = rcount ;
  740.     i = ri ;
  741.     on = ron ;
  742.     repeatflag-- ;
  743.       } else {
  744.     rcount = count ;
  745.     ri = i ;
  746.     ron = on ;
  747.       }
  748.       do {
  749.     if (count == 0) {
  750.       if (bitcounts[i] < 0) {
  751.         if (! state) repeatflag = -bitcounts[i] ;
  752.         i++ ;
  753.       }
  754.       count = bitcounts[i] ;
  755.       i++ ;
  756.       on = !on ;
  757.     }
  758.     if ((count >= pbit) && (pbit < hbit)) {
  759.       if (on) buff += power[pbit] - 1 ;
  760.       pkbyte(buff) ;
  761.       buff = 0 ;
  762.       hbit -= pbit ;
  763.       count -= pbit ;
  764.       pbit = 8 ;
  765.     } else if ((count < pbit) && (count < hbit)) {
  766.       if (on) buff += power[pbit] - power[pbit - count] ;
  767.       pbit -=  count ;
  768.       hbit -= count ;
  769.       count = 0 ;
  770.     } else {
  771.       if (on) buff += power[pbit] - power[pbit - hbit] ;
  772.       count -= hbit ;
  773.       pbit -= hbit ;
  774.       hbit = width ;
  775.       if (pbit == 0) {
  776.         pkbyte(buff) ;
  777.         buff = 0 ;
  778.         pbit = 8 ;
  779.       }
  780.     }
  781.       } while (hbit != width) ;
  782.       if (state && (repeatflag == 0)) {
  783.     count = scount ;
  784.     i = si ;
  785.     on = son ;
  786.     state = false ;
  787.       } else if (! state && (repeatflag > 0)) {
  788.     scount = count ;
  789.     si = i ;
  790.     son = on ;
  791.     state = true ;
  792.       }
  793.     }
  794.     if (pbit != 8) pkbyte(buff) ;
  795.   }
  796.   if (predpkloc != pkloc) {
  797.     fprintf(stderr, " Bad predicted character length: character %d!\n", car);
  798.     jumpout() ;
  799.   }
  800.   pbm_freerow(zerorow); 
  801.   pbm_freerow(onesrow); 
  802.   free((char *)repeatptr);
  803.   free((char *)bitcounts);
  804. }
  805.  
  806. usage()
  807. {
  808.   fprintf(stderr, " Usage: pbmtopk pkfile[.pk] tfmfile[.tfm] dpi\n") ;
  809.   fprintf(stderr, "                [-s designsize] [-p num param...]\n");
  810.   fprintf(stderr, "                [-C codingscheme ] [-F family]\n");
  811.   fprintf(stderr, "                [-c num | <char>]...\n");
  812.   fprintf(stderr, " <char> is:     [-W tfmwidth] [-H tfmheight] [-D tfmdepth]\n");
  813.   fprintf(stderr, "                [-I ital_corr] [-h horiz] [-v vert]\n") ;
  814.   fprintf(stderr, "                [-x xoffset] [-y yoffset] file\n") ;
  815.   fprintf(stderr, " or:            -f optfile\n") ;
  816.   jumpout() ;
  817. }
  818.  
  819. checkchar()
  820. {
  821.   if (car < 0 || car >= MAXPKCHAR) {
  822.     fprintf(stderr, " Character must be in range 0 to %d (-c)!\n",
  823.         MAXPKCHAR-1) ;
  824.     jumpout() ;
  825.   }
  826. }
  827.  
  828. optionfile(name)
  829.      char *name ;
  830. {
  831.   FILE *fp ;
  832.   char buffer[MAXOPTLINE] ;
  833.   
  834.   if (!strcmp(name, "-")) fp = stdin ;
  835.   else if ((fp = fopen(name, "r")) == NULL) {
  836.     fprintf(stderr, " Can't open option file %s!\n", name) ;
  837.     jumpout() ;
  838.   }
  839.   while (!feof(fp)) {
  840.     char *here = buffer;
  841.  
  842.     if (fgets(buffer, MAXOPTLINE, fp) == NULL) break ;
  843.     while (isspace(*here)) here++ ;
  844.     if (*here && *here == '=') {
  845.       if (sscanf(here+1, "%d", &car) != 1) {
  846.     fprintf(stderr, "Bad option file line %s!\n", buffer) ;
  847.     jumpout() ;
  848.       }
  849.     } else if (*here && *here != '%' && *here != '#') {
  850.       char str[NAMELENGTH] ;
  851.       integer i, n;
  852.       
  853.       checkchar() ;
  854.       if (sscanf(here, "%s%n", str, &n) != 1) {
  855.     fprintf(stderr, "Bad option file line %s!\n", buffer) ;
  856.     jumpout() ;
  857.       }
  858.       filename[car] =
  859.     (char *)malloc((unsigned int)(sizeof(char)*(strlen(str)+1))) ;
  860.       strcpy(filename[car], str) ;
  861.       for (i = 1; i < 256; i<<=1) {
  862.     here += n;
  863.     if (sscanf(here, "%s%n", str, &n) != 1) break ;
  864.     if (strcmp(str, "*")) {
  865.       charflags[car] |= i ;
  866.       switch (i) {
  867.       case XOFFSET:
  868.         xoffset[car] = atoi(str) ;
  869.         break ;
  870.       case YOFFSET:
  871.         yoffset[car] = atoi(str) ;
  872.         break ;
  873.       case HORZESC:
  874.         horzesc[car] = atoi(str) ;
  875.         break ;
  876.       case VERTESC:
  877.         vertesc[car] = atoi(str) ;
  878.         break ;
  879.       case TFMWIDTH:
  880.         tfmindex[car] = add_tfmwidth(fixword(atof(str))) ;
  881.         break ;
  882.       case TFMHEIGHT:
  883.         hgtindex[car] = add_tfmheight(fixword(atof(str))) ;
  884.         break ;
  885.       case TFMDEPTH:
  886.         depindex[car] = add_tfmdepth(fixword(atof(str))) ;
  887.         break ;
  888.       case TFMITALIC:
  889.         italindex[car] = add_tfmitalic(fixword(atof(str))) ;
  890.         break ;
  891.       }
  892.     }
  893.       }
  894.       car++ ;
  895.     }
  896.   }
  897.   if (fp != stdin) fclose(fp) ;
  898. }
  899.  
  900. dialog(gargc, gargv)
  901.      int gargc ;
  902.      char **gargv ;
  903. {
  904.   integer i, hesc, vesc, xoff, yoff, tfwid, tfdep, tfhgt, tfital ;
  905.   byte flags ;
  906.   
  907.   if (--gargc < 1) usage() ;
  908.   strcpy(pkname, *++gargv) ;
  909.   add_suffix(pkname, "pk") ;
  910.   
  911.   if (--gargc < 1) usage() ;
  912.   strcpy(tfmname, *++gargv) ;
  913.   add_suffix(tfmname, "tfm") ;
  914.   
  915.   if (--gargc < 1) usage() ;
  916.   resolution = atoi(*++gargv) ;
  917.   if (resolution < 1 || resolution > 32767) {
  918.     fprintf(stderr, " Unlikely resolution %d dpi!\n", resolution);
  919.     jumpout();
  920.   }
  921.   
  922.   car = flags = hesc = vesc = xoff = yoff = tfwid = 0;
  923.   while (++gargv, --gargc) {
  924.     if (gargv[0][0] == '-' && gargv[0][1]) {
  925.       char c, *p;
  926.       c = gargv[0][1] ;
  927.       if (gargv[0][2]) p = *gargv + 2 ;
  928.       else if (++gargv, --gargc) p = *gargv ;
  929.       else usage() ;
  930.       switch (c) {
  931.       case 'C':
  932.     codingscheme = p;
  933.     break ;
  934.       case 'F':
  935.     familyname = p;
  936.     break ;
  937.       case 'c':
  938.     car = atoi(p) ;
  939.     break ;
  940.       case 's':
  941.     designsize = fixword(atof(p));
  942.     if (designsize < 1048576) {
  943.       fprintf(stderr, " Design size %f out of range!\n",
  944.           unfixword(designsize));
  945.       jumpout() ;
  946.     }
  947.       case 'h':
  948.     hesc = atoi(p) ;
  949.     flags |= HORZESC ;
  950.     break ;
  951.       case 'v':
  952.     vesc = atoi(p) ;
  953.     flags |= VERTESC ;
  954.     break ;
  955.       case 'x':
  956.     xoff = atoi(p) ;
  957.     flags |= XOFFSET ;
  958.     break ;
  959.       case 'y':
  960.     yoff = atoi(p) ;
  961.     flags |= YOFFSET ;
  962.     break ;
  963.       case 'W':
  964.     tfwid = fixword(atof(p)) ;
  965.     flags |= TFMWIDTH ;
  966.     break ;
  967.       case 'H':
  968.     tfhgt = fixword(atof(p)) ;
  969.     flags |= TFMHEIGHT ;
  970.     break ;
  971.       case 'D':
  972.     tfdep = fixword(atof(p)) ;
  973.     flags |= TFMDEPTH ;
  974.     break ;
  975.       case 'I':
  976.     tfital = fixword(atof(p)) ;
  977.     flags |= TFMITALIC ;
  978.     break ;
  979.       case 'f':
  980.     optionfile(p) ;
  981.     break ;
  982.       case 'p':
  983.     numparam = atoi(p);
  984.     if (numparam < 1 || numparam > 30) {
  985.       fprintf(stderr, " Parameter count %d out of range!\n", numparam);
  986.       jumpout();
  987.     }
  988.     for (i=0; i<numparam; i++)
  989.       if (++gargv,--gargc) parameters[i] = fixword(atof(*gargv)) ;
  990.       else {
  991.         fprintf(stderr, " Not enough parameters (-p)!\n");
  992.         jumpout() ;
  993.       }
  994.     break ;
  995.       default:
  996.     usage() ;
  997.       }
  998.     } else  {
  999.       checkchar() ;
  1000.       if (flags & TFMWIDTH)
  1001.     tfmindex[car] = add_tfmwidth(tfwid);
  1002.       if (flags & TFMDEPTH)
  1003.     depindex[car] = add_tfmdepth(tfdep);
  1004.       if (flags & TFMHEIGHT)
  1005.     hgtindex[car] = add_tfmheight(tfhgt);
  1006.       if (flags & TFMITALIC)
  1007.     italindex[car] = add_tfmitalic(tfital);
  1008.       horzesc[car] = hesc ;
  1009.       vertesc[car] = vesc ;
  1010.       xoffset[car] = xoff ;
  1011.       yoffset[car] = yoff ;
  1012.       filename[car] = *gargv ;
  1013.       charflags[car] = flags ;
  1014.       car++ ;
  1015.       flags = 0;
  1016.     }
  1017.   }
  1018. }
  1019.  
  1020. main(argc, argv)
  1021.      int argc ;
  1022.      char *argv[] ;
  1023. {
  1024.   initialize() ;
  1025.   dialog(argc, argv) ;
  1026.   hppp = round((resolution<<16) / 72.27) ;
  1027.   add_suffix(pkname, "pk") ;
  1028.   add_suffix(tfmname, "tfm") ;
  1029.   if (!strcmp(pkname, "-")) pkfile = stdout;
  1030.   else if ((pkfile = fopen(pkname, "w")) == NULL) {
  1031.     fprintf(stderr, " Can't open PK file %s!\n", pkname);
  1032.     jumpout() ;
  1033.   }
  1034.   if (!strcmp(tfmname, "-")) tfmfile = stdout ;
  1035.   else if ((tfmfile = fopen(tfmname, "w")) == NULL) {
  1036.     fprintf(stderr, " Can't open TFM file %s!\n", tfmname);
  1037.     jumpout();
  1038.   }
  1039.   writepreamble() ;
  1040.   for (car = 0 ; car < MAXPKCHAR ; car++)
  1041.     if (filename[car]) {
  1042.       readcharacter() ;
  1043.       shipcharacter() ;
  1044.     }
  1045.   writepostamble() ;
  1046.   writetfmfile() ;
  1047.   if (pkfile != stdout) fclose(pkfile) ;
  1048.   if (tfmfile != stdout) fclose(tfmfile) ;
  1049.   exit(0);
  1050. }
  1051.